package cn.edu.swu.syz.db;

import org.apache.commons.dbcp2.BasicDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

public class DatabaseService {

    public final static String CONTEXT_KEY = "DATABASE_SERVICE";
    private BasicDataSource dataSource = null; // 连接池变量
    private static final DatabaseService instance = new DatabaseService(); // 单例实例

    // 关键：单例模式的构造方法必须为 private，禁止外部 new
    public DatabaseService() {
        // 构造方法中检查并初始化（双重保障）
        if (dataSource == null) {
            init(); // 若未初始化，强制调用 init()
        }
    }

    // 获取单例实例
    public static DatabaseService getInstance() {
        return instance;
    }

    // 初始化连接池
    public void init() {
        if (dataSource == null) { // 避免重复初始化
            dataSource = new BasicDataSource();
            dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/bookstore?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true");
            dataSource.setUsername("root");
            dataSource.setPassword("123456"); // 确保与你的 MySQL 密码一致

            // 连接池参数
            dataSource.setInitialSize(3);
            dataSource.setMaxTotal(6);
            dataSource.setMaxIdle(4);
            dataSource.setMinIdle(2);
            dataSource.setMaxWaitMillis(10000);
            System.out.println("DatabaseService 内部初始化连接池完成");
        }
    }

    // 获取数据库连接（私有，仅内部使用）
    private Connection getConnection() throws SQLException {
        if (dataSource == null) {
            throw new SQLException("连接池未初始化！请检查 init() 方法是否被调用");
        }
        return dataSource.getConnection();
    }

    // 关闭连接池（项目关闭时调用）
    public void closeDataSource() {
        if (dataSource != null) {
            try {
                dataSource.close();
                System.out.println("连接池已关闭");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 1. 基础查询方法（无参数）
    public List query(String sql, ResultSetVisitor visitor) throws SQLException {
        try (Connection connection = getConnection();
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(sql)) {
            return visitor.visit(resultSet);
        }
    }

    // 2. 新增：参数化查询方法（支持 ? 占位符）
    public List query(String sql, ResultSetVisitor visitor, Object... params) throws SQLException {
        try (Connection connection = getConnection();
             PreparedStatement pstmt = connection.prepareStatement(sql)) {
            // 设置参数（索引从 1 开始）
            setParameters(pstmt, params);
            try (ResultSet resultSet = pstmt.executeQuery()) {
                return visitor.visit(resultSet);
            }
        }
    }

    // 3. 基础执行方法（无参数，用于增删改）
    public boolean execute(String sql) throws SQLException {
        try (Connection connection = getConnection();
             Statement statement = connection.createStatement()) {
            return statement.execute(sql);
        }
    }

    // 4. 新增：参数化执行方法（支持 ? 占位符，用于增删改）
    public boolean execute(String sql, Object... params) throws SQLException {
        try (Connection connection = getConnection();
             PreparedStatement pstmt = connection.prepareStatement(sql)) {
            // 设置参数（索引从 1 开始）
            setParameters(pstmt, params);
            return pstmt.execute();
        }
    }

    // 辅助方法：给 PreparedStatement 设置参数
    private void setParameters(PreparedStatement pstmt, Object... params) throws SQLException {
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]); // 参数索引从 1 开始
            }
        }
    }

}